package com.huiminpay.transaction.service;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.huiminpay.merchant.common.cache.Cache;
import com.huiminpay.merchant.common.cache.domain.BusinessException;
import com.huiminpay.merchant.common.cache.domain.CommonErrorCode;
import com.huiminpay.merchant.common.cache.util.RedisUtil;
import com.huiminpay.transaction.api.PayChannelService;
import com.huiminpay.transaction.convert.PayChannelParamConvert;
import com.huiminpay.transaction.convert.PlatformChannelConvert;
import com.huiminpay.transaction.dto.PayChannelDTO;
import com.huiminpay.transaction.dto.PayChannelParamDTO;
import com.huiminpay.transaction.dto.PlatformChannelDTO;
import com.huiminpay.transaction.entity.AppPlatformChannel;
import com.huiminpay.transaction.entity.PayChannel;
import com.huiminpay.transaction.entity.PayChannelParam;
import com.huiminpay.transaction.entity.PlatformChannel;
import com.huiminpay.transaction.mapper.AppPlatformChannelMapper;
import com.huiminpay.transaction.mapper.PayChannelParamMapper;
import com.huiminpay.transaction.mapper.PlatformChannelMapper;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Collections;
import java.util.List;

import static com.sun.corba.se.impl.util.RepositoryId.cache;


@Service
public class PayChannelServiceImpl implements PayChannelService {

    @Autowired
    private PlatformChannelMapper platformChannelMapper;
    @Autowired
    private AppPlatformChannelMapper appPlatformChannelMapper;
    @Autowired
    private PayChannelParamMapper payChannelParamMapper;
    @Autowired
    Cache cache;
    //获取平台服务类型
    @Override
    public List<PlatformChannelDTO> queryPlatformChannel() {
        List<PlatformChannel> platformChannels = platformChannelMapper.selectList(null);
        List<PlatformChannelDTO> platformChannelDTOS = PlatformChannelConvert.INSTANCE.listentity2listdto(platformChannels);
        return platformChannelDTOS;
    }
    //为应用绑定平台服务类型
    @Override
    public void bindPlatformChannelForApp(String appId, String platformChannel) throws BusinessException {
        //根据应用id和平台服务的code查询是否已经绑定[app_platform_channel]
        LambdaQueryWrapper<AppPlatformChannel> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(AppPlatformChannel::getAppId, appId);
        queryWrapper.eq(AppPlatformChannel::getPlatformChannel, platformChannel);
        AppPlatformChannel appPlatformChannel = appPlatformChannelMapper.selectOne(queryWrapper);
        //判断是否已经绑定(是否为null)
        if(appPlatformChannel == null){
            appPlatformChannel = new AppPlatformChannel();
            appPlatformChannel.setAppId(appId);
            appPlatformChannel.setPlatformChannel(platformChannel);
            appPlatformChannelMapper.insert(appPlatformChannel);
        }
    }

    //根据appId和platformChannel查询服务类型绑定状态
    @Override
    public int queryAppBindPlatformChannel(String appId, String platformChannel) throws BusinessException {
        LambdaQueryWrapper<AppPlatformChannel> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(AppPlatformChannel::getAppId, appId);
        queryWrapper.eq(AppPlatformChannel::getPlatformChannel, platformChannel);
        Integer count = appPlatformChannelMapper.selectCount(queryWrapper);
        if(count>0){
            return 1;
        }
        return 0;
    }
    //根据平台服务类型获取支付渠道列表
    @Override
    public List<PayChannelDTO> queryPayChannelByPlatformChannel(String platformChannelCode) throws BusinessException {
        return platformChannelMapper.selectPayChannelByPlatformChannel(platformChannelCode);
    }
    //保存支付渠道参数
    @Override
    public void savePayChannelParam(PayChannelParamDTO payChannelParamdto) throws BusinessException {
       //合法性校验
        if(payChannelParamdto==null
                ||StringUtils.isBlank(payChannelParamdto.getAppId())
                ||StringUtils.isBlank(payChannelParamdto.getPlatformChannelCode())
                ||StringUtils.isBlank(payChannelParamdto.getPayChannel())){
            throw new BusinessException(CommonErrorCode.E_300009);
        }
       //根据应用Id和平台服务code查询应用和服务绑定的id
        Long appPlatformChannelId = selectIdByAppPlatformChannel(payChannelParamdto.getAppId(),payChannelParamdto.getPlatformChannelCode());
        if(appPlatformChannelId==null){
            throw new BusinessException(CommonErrorCode.E_300010);
        }
        //根据应用和服务绑定的id和支付渠道编码查询渠道参数是否存在
        LambdaQueryWrapper<PayChannelParam> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(PayChannelParam::getPayChannel, payChannelParamdto.getPayChannel());
        queryWrapper.eq(PayChannelParam::getAppPlatformChannelId, appPlatformChannelId);
        PayChannelParam payChannelParam = payChannelParamMapper.selectOne(queryWrapper);
        //如果渠道参数不存在则执行新增，否则执行修改
        if(payChannelParam!=null){
            //修改
            payChannelParam.setChannelName(payChannelParamdto.getChannelName());
            payChannelParam.setParam(payChannelParamdto.getParam());
            payChannelParamMapper.updateById(payChannelParam);
        }else {
            //新增
            PayChannelParam payChannelParam1 = PayChannelParamConvert.INSTANCE.dto2entity(payChannelParamdto);
            payChannelParam1.setId(null);
            payChannelParam1.setAppPlatformChannelId(appPlatformChannelId);
            payChannelParamMapper.insert(payChannelParam1);

        }
        //缓存更新
        updateCache(payChannelParamdto.getAppId(),payChannelParamdto.getPlatformChannelCode());
    }
    //缓存更新方法
    private void updateCache(String appId, String platformChannel) {
        //处理redis缓存
        //1.key的构建
        String redisKey = RedisUtil.keyBuilder(appId, platformChannel);
        //2.查询redis,检查key是否存在
        Boolean exists = cache.exists(redisKey);
        if (exists) {//存在，则清除
            //删除原有缓存
            cache.del(redisKey);
        }
        //3.从数据库查询应用的服务类型对应的实际支付参数，并重新存入缓存
        List<PayChannelParamDTO> paramDTOS = queryPayChannelParamByAppAndPlatform(appId,platformChannel);
        if (paramDTOS != null) {
            //存入缓存
            cache.set(redisKey, JSON.toJSON(paramDTOS).toString());
        }
    }
    //根据appId和platformChannel查询支付渠道参数列表（可能是多个）
    @Override
    public List<PayChannelParamDTO> queryPayChannelParamByAppAndPlatform(String appId, String platformChannel) throws BusinessException {
        //先从redis查询，如果有则返回
        //从缓存查询
        //1.key的构建
        String redisKey = RedisUtil.keyBuilder(appId, platformChannel);
        //是否有缓存
        Boolean exists = cache.exists(redisKey);
        if(exists){
            //从redis获取支付渠道参数列表（json串）
            String PayChannelParamDTO_String = cache.get(redisKey);
            //将json串转成 List<PayChannelParamDTO>
            List<PayChannelParamDTO> payChannelParamDTOS = JSON.parseArray(PayChannelParamDTO_String, PayChannelParamDTO.class);
            return payChannelParamDTOS;
        }
        //缓存中没有 则从数据库查询  根据应用和服务类型找到它们绑定id
        //查出应用id和服务类型代码在app_platform_channel主键
        Long appPlatformChannelId = selectIdByAppPlatformChannel(appId,platformChannel);
        if(appPlatformChannelId==null){
            return null;
        }
        //根据appPlatformChannelId从pay_channel_param查询所有支付参数
        List<PayChannelParam> payChannelParams = payChannelParamMapper.selectList(
                new LambdaQueryWrapper<PayChannelParam>()
                        .eq(PayChannelParam::getAppPlatformChannelId, appPlatformChannelId));
        //保存redis里
        cache.set(redisKey, JSON.toJSON(payChannelParams).toString());
        return PayChannelParamConvert.INSTANCE.listentity2listdto(payChannelParams);
    }
    //根据appId、platformChannel和payChannel查询支付渠道参数（一个）
    @Override
    public PayChannelParamDTO queryParamByAppPlatformAndPayChannel(String appId, String platformChannel, String payChannel) throws BusinessException {
        List<PayChannelParamDTO> payChannelParamdtos = queryPayChannelParamByAppAndPlatform(appId, platformChannel);
        for(PayChannelParamDTO payChannelParam:payChannelParamdtos){
            if(payChannelParam.getPayChannel().equals(payChannel)){
                return payChannelParam;
            }
        }
        return null;
    }

    //根据应用Id和平台服务code查询应用和服务绑定的id（返回值是id）
    public Long selectIdByAppPlatformChannel(String appId,String platformChannelCode){
        LambdaQueryWrapper<AppPlatformChannel> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(AppPlatformChannel::getAppId, appId);
        queryWrapper.eq(AppPlatformChannel::getPlatformChannel, platformChannelCode);
        AppPlatformChannel appPlatformChannel = appPlatformChannelMapper.selectOne(queryWrapper);
        if(appPlatformChannel!=null){
            return appPlatformChannel.getId();
        }
        return null;
    }
}
